/***********************************************************************************
 * 文件名： mcu_adc.h
 * 版本： 3
 * 说明：
 * 		SC8 系列 的ADC外设驱动。使用说明见头文件。在 sc8_driver_config.h 文件中可配置初始状态。
 * 修改记录：
 * 	2021/04/28: 初版。 刘言。
 *  2022/01/21：兼容SC8P171xE系列
 *  2022/04/01: 新增ADC量程定义
***********************************************************************************/
#ifndef _MCU_ADC_H
#define _MCU_ADC_H

#include "mcu.h"

// ADC满量程定义
#define ADC_FULL_VALUE 255

#if SC8P_MCU_TYPE == SC8P1715
// ADC初始化
// 按照配置文件中的初始参数进行初始化。注意中断初始状态在 Mcu_Init 中已统一初始化。
#define Adc_Init()                                                   \
    {                                                                \
        ADCON0 = (ADC_CLK_SEL << 6) | (ADC_CH << 2) | (ADC_ON << 0); \
        /*ADCON1 = (0 << 7);*/                                       \
    }

// [异步]启动AD转换
// u8_ch : 通道号，取值范围 0~15
// 转换完成后ADIF=1,如果开启ADC中断将会产生中断，可在中断服务函数中获取结果
#define Adc_Start(u8_ch)        \
    {                           \
        ADCON0 &= 0XC3;         \
        ADCON0 |= (u8_ch << 2); \
        GODONE = 1;             \
    }

// 获取现在的通道号
#define Adc_GetCH() ((ADCON0 & 0x3F) >> 2)

#elif SC8P_MCU_TYPE == SC8P171xE

// 为了节约代码而暴露变量
extern u8 Adc_mAdcFEC;

// ADC初始化
// 按照配置文件中的初始参数进行初始化。注意中断初始状态在 Mcu_Init 中已统一初始化。
#define Adc_Init()                                                   \
    {                                                                \
        ADCON0 = (ADC_CLK_SEL << 6) | (ADC_CH << 2) | (ADC_ON << 0); \
        ADCON1 = (0 << 7) | (ADC_TADSEL << 3);                       \
    }

// [异步]启动AD转换
// u8_ch : 通道号，取值范围 0~15
// 转换完成后ADIF=1,如果开启ADC中断将会产生中断，可在中断服务函数中获取结果
#define Adc_Start(u8_ch)        \
    {                           \
        ADCON0 &= 0XC3;         \
        ADCON0 |= (u8_ch << 2); \
        __delay_us(ADC_DELAY);  \
        Adc_mAdcFEC = 0;        \
        GODONE = 1;             \
    }

// 获取现在的通道号
#define Adc_GetCH() ((ADCON0 & 0x3F) >> 2)

#elif SC8P_MCU_TYPE == SC8F577x

// 为了节约代码而暴露变量
extern u8 Adc_mAdcFEC;

// ADC初始化
// 按照配置文件中的初始参数进行初始化。注意中断初始状态在 Mcu_Init 中已统一初始化。
#define Adc_Init()                                                                     \
    {                                                                                  \
        ADCON1 = (0 << 7) | ((ADC_CH & 0x10) << 2) | ((ADC_CLK_SEL & 0x04) << 3);      \
        ADCON0 = ((ADC_CLK_SEL & 0x03) << 6) | ((ADC_CH & 0x0F) << 2) | (ADC_ON << 0); \
    }

// [异步]启动AD转换
// u8_ch : 通道号，取值范围 0~15
// 转换完成后ADIF=1,如果开启ADC中断将会产生中断，可在中断服务函数中获取结果
#define Adc_Start(u8_ch)            \
    {                               \
        CHS4 = ((u8_ch)&0x10) >> 4; \
        ADCON0 &= 0XC3;             \
        ADCON0 |= (u8_ch << 2);     \
        __delay_us(ADC_DELAY);      \
        Adc_mAdcFEC = 0;            \
        GODONE = 1;                 \
    }

// 获取现在的通道号
#define Adc_GetCH() (((ADCON0 & 0x3F) >> 2) + ((ADCON1 & 0x40) >> 2))

#endif

// 获取最后一次转换结果
#define Adc_GetResult() ADRESH

// 获取中断标志
#define Adc_GetIntFlag() ADIF

// 清除中断标志
#define Adc_ClrIntFlag() ADIF = 0

// 使能ADC
#define Adc_Enable() \
    {                \
        ADON = 1;    \
    }

// 失能ADC，如果还在转换中，直接结束，可以省电
#define Adc_Disable() \
    {                 \
        GODONE = 0;   \
        ADON = 0;     \
    }

// 启动一次AD转换，并返回结果
// 转换时临时关闭了ADC中断
u8 Adc_GetOnce(u8 ch);

#if SC8P_MCU_TYPE == SC8P171xE || SC8P_MCU_TYPE == SC8F577x
// 使用ADC中断时，需要纠错 建议100us定时调用
void Adc_EvTimingFEC();
#endif

#endif
